package org.dromara.wms.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseService;
import org.dromara.wms.domain.WmsBom;
import org.dromara.wms.domain.WmsBomLine;
import org.dromara.wms.domain.WmsBomProcess;
import org.dromara.wms.mapper.WmsBomLineMapper;
import org.dromara.wms.mapper.WmsBomMapper;
import org.dromara.wms.mapper.WmsBomProcessMapper;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 物料清单Service实现类
 */
@RequiredArgsConstructor
@Service
public class WmsBomServiceImpl extends BaseService {
  private final WmsBomMapper bomMapper;
  private final WmsBomLineMapper bomLineMapper;
  private final WmsBomProcessMapper processMapper;

  /**
   * 根据ID查询物料清单
   */
  public WmsBom queryById(Long id) {
    return bomMapper.selectById(id);
  }

  /**
   * 分页查询物料清单列表
   */
  public TableDataInfo<WmsBom> queryPageList(WmsBom bo, PageQuery pageQuery) {
//        LambdaQueryWrapper<WmsBom> lqw = buildQueryWrapper(bo);
    Page<WmsBom> result = bomMapper.queryPageList(pageQuery.build(), bo);
    return TableDataInfo.build(result);
  }

  /**
   * 查询物料清单列表
   */
  public List<WmsBom> queryList(WmsBom bo) {
    return bomMapper.queryPageList(bo);
  }

  /**
   * 构建查询条件
   */
  private LambdaQueryWrapper<WmsBom> buildQueryWrapper(WmsBom bo) {
    Map<String, Object> params = bo.getParams();
    LambdaQueryWrapper<WmsBom> lqw = Wrappers.lambdaQuery();
    lqw.eq(bo.getProductId() != null, WmsBom::getProductId, bo.getProductId());
    lqw.eq(bo.getProductName() != null, WmsBom::getProductName, bo.getProductName());
    lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
      WmsBom::getUpdateTime, params.get("beginUpdateTime"), params.get("endUpdateTime"));
    return lqw;
  }

  /**
   * 新增物料清单
   */
  public Boolean insert(WmsBom bo) {
    validEntityBeforeSave(bo);
    return bomMapper.insert(bo) > 0;
  }

  /**
   * 更新物料清单
   */
  public Boolean update(WmsBom bo) {
    validEntityBeforeSave(bo);
    return bomMapper.updateById(bo) > 0;
  }

  /**
   * 保存前的数据校验
   *
   * @param entity 实体类数据
   */
  private void validEntityBeforeSave(WmsBom entity) {
    //TODO 做一些数据校验,如唯一约束
  }

  /**
   * 根据ID删除物料清单
   */
  public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
    if (isValid) {
      //TODO 做一些业务上的校验,判断是否需要校验
    }
    return bomMapper.deleteBatchIds(ids) > 0;
  }

  /**
   * ========================================操作line表开始===============================
   */

  public List<WmsBomLine> queryLineList(WmsBomLine bo) {
    List<WmsBomLine> wmsBomLines = bomLineMapper.queryLineList(bo);
    Map<Number, List<Long>> parentidMap = new HashMap<>();
    for (WmsBomLine wmsBomLine : wmsBomLines) {
      List<Long> longs = queryParentIdsWrapper(bo.getParentId(), wmsBomLine);
      if (parentidMap.containsKey(wmsBomLine.getProductId())) {
        List<Long> parentIds = parentidMap.get(wmsBomLine.getProductId());
        List<Long> newParentIds = Stream.concat(parentIds.stream(), longs.stream())
          .distinct()
          .collect(Collectors.toList());
        parentidMap.put(wmsBomLine.getProductId(), newParentIds);
      } else {
        parentidMap.put(wmsBomLine.getProductId(), longs);
      }
      wmsBomLine.setChildIds(queryChildIdsWrapper(wmsBomLine));
    }
    for (WmsBomLine wmsBomLine : wmsBomLines) {
      wmsBomLine.setParentIds(parentidMap.get(wmsBomLine.getProductId()));
    }
    return wmsBomLines;
  }

  /**
   * 根据ID查询物料清单明细
   */
  public WmsBomLine queryLineById(WmsBomLine bo) {
    LambdaQueryWrapper<WmsBomLine> lqw = Wrappers.lambdaQuery();
    lqw.eq(WmsBomLine::getId, bo.getId());
    lqw.eq(bo.getProductId() != null, WmsBomLine::getProductId, bo.getProductId());
    lqw.eq(bo.getParentId() != null, WmsBomLine::getParentId, bo.getParentId());
    return bomLineMapper.selectOne(lqw);
  }

  /**
   * 构建查询条件
   */
  private LambdaQueryWrapper<WmsBomLine> buildQueryWrapper(WmsBomLine bo) {
//        Map<String, Object> params = bo.getParams();
    LambdaQueryWrapper<WmsBomLine> lqwp = Wrappers.lambdaQuery();
    LambdaQueryWrapper<WmsBomLine> lqw = Wrappers.lambdaQuery();
    if (bo.getParentId() != null) {
//      allProductIds.clear();
//      List<Long> productIds = queryWrapper(bo.getId(), bo.getParentId());
//      productIds.add(bo.getParentId());
//      List<Long> uniqueProductIds = productIds.stream().distinct().collect(Collectors.toList());
//      lqw.eq(bo.getId() != null, WmsBomLine::getId, bo.getId())
//        .in(CollectionUtils.isNotEmpty(productIds), WmsBomLine::getParentId, uniqueProductIds);
      return lqw;
    }
    lqw.eq(bo.getId() != null, WmsBomLine::getId, bo.getId());
    lqw.eq(bo.getProductId() != null, WmsBomLine::getProductId, bo.getProductId());
//        lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
//                WmsBomLine::getUpdateTime, params.get("beginUpdateTime"), params.get("endUpdateTime"));
    return lqw;
  }


  /**
   * 查询父级ID
   */
  public List<Long> queryParentIdsWrapper(Long OldParentId, WmsBomLine bo) {
    LambdaQueryWrapper<WmsBomLine> lqw = Wrappers.lambdaQuery();
    List<Long> allParentIds = new ArrayList<>();
    lqw.eq(WmsBomLine::getId, bo.getId());
    lqw.eq(WmsBomLine::getProductId, bo.getParentId());
    List<WmsBomLine> wmsBomLines = bomLineMapper.selectList(lqw);
    if (wmsBomLines.size() > 0) {
      wmsBomLines.forEach(wmsBomLine -> {
        List<Long> parentIds = queryParentIdsWrapper(OldParentId, wmsBomLine);
        allParentIds.addAll(parentIds);
      });
      allParentIds.add(bo.getParentId());
      return allParentIds;
    }
    allParentIds.add(bo.getParentId());
    return allParentIds;
  }

  /**
   * 查询子级ID
   */
  public List<Long> queryChildIdsWrapper(WmsBomLine bo) {
    LambdaQueryWrapper<WmsBomLine> lqw = Wrappers.lambdaQuery();
    List<Long> allchildIds = new ArrayList<>();
    lqw.eq(WmsBomLine::getId, bo.getId());
    lqw.eq(WmsBomLine::getParentId, bo.getProductId());
    List<WmsBomLine> wmsBomLines = bomLineMapper.selectList(lqw);
    List<Long> childIds = wmsBomLines.stream().map(WmsBomLine::getProductId).collect(Collectors.toList());
    if (wmsBomLines.size() > 0) {
      wmsBomLines.forEach(wmsBomLine -> {
        List<Long> parentIds = queryChildIdsWrapper(wmsBomLine);
        allchildIds.addAll(parentIds);
      });
      allchildIds.addAll(childIds);
      return allchildIds;
    }
    return allchildIds;
  }

  /**
   * 新增物料清单明细
   */
  public Boolean insertLine(WmsBomLine bo) {
    validLineEntityBeforeSave(bo);
    return bomLineMapper.insert(bo) > 0;
  }

  /**
   * 更新物料清单明细
   */
  public Boolean updateLine(WmsBomLine bo) {
    WmsBomLine oldLine = bo.getOldLine();
    validLineEntityBeforeSave(bo);
    LambdaQueryWrapper<WmsBomLine> lqwp = Wrappers.lambdaQuery();
    lqwp.eq(WmsBomLine::getParentId, oldLine.getProductId());
    List<WmsBomLine> wmsBomLines = bomLineMapper.selectList(lqwp);
    if (wmsBomLines.size() > 0) {
      // 对每个 wmsBomLine 创建一个更新对象
      List<LambdaUpdateWrapper<WmsBomLine>> updateWrappers = new ArrayList<>();
      for (WmsBomLine wmsBomLine : wmsBomLines) {
        Long id = wmsBomLine.getId();
        Long productId = wmsBomLine.getProductId();
        Long parentId = wmsBomLine.getParentId();
        LambdaUpdateWrapper<WmsBomLine> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.set(WmsBomLine::getParentId, bo.getProductId())
          .eq(WmsBomLine::getId, id)
          .eq(WmsBomLine::getProductId, productId)
          .eq(WmsBomLine::getParentId, parentId);
        updateWrappers.add(updateWrapper);
      }
      // 批量更新
      for (int i = 0; i < wmsBomLines.size(); i++) {
        bomLineMapper.update(wmsBomLines.get(i), updateWrappers.get(i));
      }
    }

    LambdaQueryWrapper<WmsBomLine> lqw = Wrappers.lambdaQuery();
    lqw.eq(WmsBomLine::getId, oldLine.getId());
    lqw.eq(WmsBomLine::getProductId, oldLine.getProductId());
    lqw.eq(WmsBomLine::getParentId, oldLine.getParentId());

    return bomLineMapper.update(bo, lqw) > 0;
  }

  /**
   * 保存前的数据校验
   *
   * @param entity 实体类数据
   */
  private void validLineEntityBeforeSave(WmsBomLine entity) {
    //TODO 做一些数据校验,如唯一约束
  }

  private List<WmsBomLine> lineList = new ArrayList<>();

  public List<WmsBomLine> deleteWrapper(Long id, Long parentId) {
    LambdaQueryWrapper<WmsBomLine> lqw = Wrappers.lambdaQuery();
    lqw.eq(WmsBomLine::getId, id);
    lqw.eq(WmsBomLine::getParentId, parentId);
    List<WmsBomLine> wmsBomLines = bomLineMapper.selectList(lqw);
    if (wmsBomLines.size() > 0) {
      for (WmsBomLine wmsBomLine : wmsBomLines) {
        deleteWrapper(id, wmsBomLine.getProductId()); // 递归调用
      }
    }
    lineList.addAll(wmsBomLines);
    return lineList; // 返回最终合并的产品ID列表
  }


  /**
   * 删除物料清单
   *
   * @param bo      物料清单对象，包含要删除的物料信息
   * @param isValid 标志是否进行有效性验证
   * @return 返回删除操作是否成功
   */
  public Boolean deleteLineWithValid(WmsBomLine bo, Boolean isValid) {
    // 如果isValid为true，则进行一些业务上的校验
    if (isValid) {
      //TODO 做一些业务上的校验,判断是否需要校验
//      if(bo.getDeletes()==null){
//        List<WmsBomLine> deletes = new ArrayList<>();
//        deletes.add(bo) ;
//      }else{
//        List<WmsBomLine> deletes = bo.getDeletes();
//      }
    }

    // 获取要删除的物料清单列表
    List<WmsBomLine> deletes = bo.getDeletes();
    // 创建一个列表用于存储删除操作的查询条件
    List<LambdaQueryWrapper<WmsBomLine>> deleteWrappers = new ArrayList<>();
    // 初始化删除成功的标志为true
    boolean flag = true;

    // 如果删除的物料清单只有一项
    if (deletes.size() == 1) {
      // 清空lineList列表，准备重新添加删除的物料信息
      lineList.clear();
      // 调用deleteWrapper方法，根据物料的ID和产品ID进行删除操作
      deleteWrapper(deletes.get(0).getId(), deletes.get(0).getProductId());
      // 将删除的物料信息添加到lineList列表中
      lineList.add(deletes.get(0));
      // 遍历lineList列表，为每个物料生成删除操作的查询条件
      lineList.forEach(line -> {
        LambdaQueryWrapper<WmsBomLine> lqw = Wrappers.lambdaQuery();
        lqw.eq(WmsBomLine::getId, line.getId());
        lqw.eq(WmsBomLine::getProductId, line.getProductId());
        lqw.eq(WmsBomLine::getParentId, line.getParentId());
        deleteWrappers.add(lqw);
      });
      // 逐个执行删除操作，如果有一个删除失败，则将flag设置为false并返回
      for (int i = 0; i < lineList.size(); i++) {
        int index = bomLineMapper.delete(deleteWrappers.get(i));
        if (index <= 0) {
          flag = false;
          return flag;
        }
      }
    } else {
      // 如果删除的物料清单有多项，遍历deletes列表，为每个物料生成删除操作的查询条件
      deletes.forEach(delete -> {
        LambdaQueryWrapper<WmsBomLine> lqw = Wrappers.lambdaQuery();
        lqw.eq(WmsBomLine::getId, delete.getId());
        lqw.eq(WmsBomLine::getProductId, delete.getProductId());
        lqw.eq(WmsBomLine::getParentId, delete.getParentId());
        deleteWrappers.add(lqw);
      });
      // 逐个执行删除操作，如果有一个删除失败，则将flag设置为false并返回
      for (int i = 0; i < deletes.size(); i++) {
        int index = bomLineMapper.delete(deleteWrappers.get(i));
        if (index <= 0) {
          flag = false;
          return flag;
        }
      }
      // 返回删除操作的成功标志
      return flag;
    }
    // 返回删除操作的成功标志
    return flag;
  }
  /**
   * ========================================操作关联表开始===============================
   */
  /**
   * 根据ID查询工序清单明细
   */
  public WmsBomProcess queryProcessById(WmsBomProcess bo) {
    LambdaQueryWrapper<WmsBomProcess> lqw = Wrappers.lambdaQuery();
    lqw.eq(WmsBomProcess::getId, bo.getId());
    lqw.eq(WmsBomProcess::getProcessId, bo.getProcessId());
    lqw.eq(WmsBomProcess::getSort, bo.getSort());
    WmsBomProcess wmsBomProcess = processMapper.selectOne(lqw);
    return wmsBomProcess;
  }

  public List<WmsBomProcess> selectById(Long id) {
    LambdaQueryWrapper<WmsBomProcess> lqw = Wrappers.lambdaQuery();
    lqw.eq(WmsBomProcess::getId, id);
    return processMapper.selectList(lqw);
  }

  /**
   * 分页查询工序清单列表
   */
  public TableDataInfo<WmsBomProcess> queryProcessPageList(WmsBomProcess bo, PageQuery pageQuery) {
    LambdaQueryWrapper<WmsBomProcess> lqw = buildQueryWrapper(bo);
    Page<WmsBomProcess> result = processMapper.selectPage(pageQuery.build(), lqw);
    return TableDataInfo.build(result);
  }

  /**
   * 查询工序清单列表
   */
  public List<WmsBomProcess> queryProcessList(WmsBomProcess bo) {
    return processMapper.selectList(buildQueryWrapper(bo));
  }

  /**
   * 构建查询条件
   */
  private LambdaQueryWrapper<WmsBomProcess> buildQueryWrapper(WmsBomProcess bo) {
    LambdaQueryWrapper<WmsBomProcess> lqw = Wrappers.lambdaQuery();
    lqw.eq(bo.getId() != null, WmsBomProcess::getId, bo.getId());
    lqw.eq(bo.getProcessId() != null, WmsBomProcess::getProcessId, bo.getProcessId());
    lqw.eq(bo.getEquipmentId() != null, WmsBomProcess::getEquipmentId, bo.getEquipmentId());
    lqw.orderByAsc(WmsBomProcess::getSort);
    return lqw;
  }

  /**
   * 新增工序清单明细
   */
  public Boolean insertProcess(WmsBomProcess bo) {
    validProcessEntityBeforeSave(bo);
    return processMapper.insert(bo) > 0;
  }

  /**
   * 更新工序清单明细
   */
  public Boolean updateProcess(WmsBomProcess wmsBomProcess) {
    validProcessEntityBeforeSave(wmsBomProcess);
    LambdaQueryWrapper<WmsBomProcess> lqw = Wrappers.lambdaQuery();
    lqw.eq(WmsBomProcess::getId, wmsBomProcess.getId());
    return processMapper.update(wmsBomProcess, lqw) > 0;
  }

  private void validProcessEntityBeforeSave(WmsBomProcess entity) {
    //TODO 做一些数据校验,如唯一约束
  }


  public Boolean deleteProcessWithValid(WmsBomProcess bo, Boolean isValid) {
    if (isValid) {
      //TODO 做一些业务上的校验,判断是否需要校验
    }

    List<WmsBomProcess> deletes = bo.getDeletes();
    boolean flag = true;

    if (deletes.size() == 1) {
      LambdaQueryWrapper<WmsBomProcess> lqw = Wrappers.lambdaQuery();
      lqw.eq(WmsBomProcess::getId, bo.getId());
      lqw.eq(WmsBomProcess::getProcessId, bo.getProcessId());
      lqw.eq(WmsBomProcess::getSort, bo.getSort());
      return processMapper.delete(lqw) > 0;
    } else {
      List<LambdaQueryWrapper<WmsBomProcess>> deleteWrappers = new ArrayList<>();
      deletes.forEach(delete -> {
        LambdaQueryWrapper<WmsBomProcess> lqw = Wrappers.lambdaQuery();
        lqw.eq(WmsBomProcess::getId, delete.getId());
        lqw.eq(WmsBomProcess::getProcessId, delete.getProcessId());
        lqw.eq(WmsBomProcess::getSort, delete.getSort());
        deleteWrappers.add(lqw);
      });
      for (int i = 0; i < deletes.size(); i++) {
        int index = processMapper.delete(deleteWrappers.get(i));
        if (index <= 0) {
          flag = false;
          return flag;
        }
      }
      return flag;
    }
  }
}
